package com.elitel.frame.base.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.elitel.common.utils.SysUserUtils;
import com.elitel.frame.base.service.SysMsgPushService;
import com.elitel.frame.base.service.impl.lx.*;
import com.elitel.frame.base.utils.IdWorker2;
import com.elitel.frame.main.dao.SysMsgPushMapper;
import com.elitel.frame.main.entity.SysMsgPush;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SysMsgPushServiceImpl implements SysMsgPushService {
    @Resource
    private SysMsgPushMapper sysMsgPushMapper;
    @Resource
    LXProp lxProp;

    /*多源服务*/
    @Override
    public void dyfw() {
        log.error("===================== 多源警告定时任务 ============================");
        List<SysMsgPush> all = sysMsgPushMapper.getAllEnable("DYHSYB");
        Date now = new Date();
        int nowHour = now.getHours();
        for (SysMsgPush sysMsgPush : all) {
            try {
                Integer lock = lock(sysMsgPush);
                if (lock == 1) {
                    Date startTime = sysMsgPush.getStartTime();
                    Date endTime = sysMsgPush.getEndTime();
                    int startTimeHour = startTime.getHours();
                    int endTimeHour = endTime.getHours();
                    if (nowHour >= startTimeHour && nowHour <= endTimeHour) {
                        String cfgInfo = sysMsgPush.getCfgInfo();
                        /*json 结果参考 SysMsgPushServiceImpl2.json*/
                        JSONObject jsonObject = JSON.parseObject(cfgInfo);
                        String timeField = jsonObject.getString("timeField");
                        String sql = jsonObject.getString("sql");
                        String finalSql = getFinalSql(timeField, sql);
                        List<Map<String, Object>> list = sysMsgPushMapper.select(finalSql);
                        List<String> careFields = jsonObject.getJSONArray("careFields").stream().map(Object::toString).collect(Collectors.toList());
                        List<String> phones = jsonObject.getJSONArray("phones").stream().map(Object::toString).collect(Collectors.toList());
                        String msg = "";
                        for (Map<String, Object> resultMap : list) {
                            String tmp = "";
                            for (String careField : careFields) {
                                tmp += "," + resultMap.get(careField);
                            }
                            if (!tmp.isEmpty()) {
                                tmp += ";";
                                msg += tmp.substring(1);
                            }
                        }
                        sendMsgAndUpdate(sysMsgPush, msg, phones);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                unlock(sysMsgPush);
            }

        }
    }

    private void sendMsgAndUpdate(SysMsgPush sysMsgPush, String msg, List<String> phones) {
//        sysMsgPush.setLastErrMsg(msg);
//        sysMsgPush.setLastExecTime(new Date());
//        sysMsgPushMapper.updateJob(sysMsgPush);
        Map<String, String> sendMsg = getSendMsg(msg);
        String isSend = sendMsg.get("isSend");
        String msg1 = sendMsg.get("msg");
        if ("yes".equals(isSend)) {
            sendMesg(phones, msg1);
        }

    }

    private Map<String, String> getSendMsg(String msg) {
        Map<String, String> map = new HashMap<>();
        if (msg.isEmpty()) {
            map.put("isSend", "no");
            return map;
        }
        int hour = LocalTime.now().getHour();
        String sendMsg = "【数据服务】服务异常通知，" + (hour - 1) + "-" + hour + "时关注服务调用失败情况，";
        for (String s : msg.split(";")) {
            if (s.contains(",")) {
                String[] split = s.split(",");
                if (split.length == 2) sendMsg += "「" + split[0] + "」有" + split[1] + "次调用失败，";
            }
        }
        String finalMsg = sendMsg.substring(0, sendMsg.length() - 1) + "。";
        map.put("msg", finalMsg);
        map.put("isSend", "yes");
        return map;
    }

    private void sendMesg(List<String> phones, String content) {
        String appToken = getAppToken();
        List<String> users = new ArrayList<>();
        for (String phone : phones) {
            String staffId = getstaffId(appToken, phone);
            users.add(staffId);
        }
        ResultCommonVo.ResultObj resultObj = sendMessage(users, appToken, content);
        log.info(JSON.toJSONString(resultObj));
    }

    /**
     * 发送消息
     *
     * @return com.elitel.hydsync.entity.voentity.ResultCommonVo.ResultObj
     * @author px
     * @create 2024/2/5
     **/
    public ResultCommonVo.ResultObj sendMessage(List<String> userIdList, String appToken, String content) {
        ResultCommonVo.ResultObj resultObj = new ResultCommonVo.ResultObj();
        try {
            String requestUrl = lxProp.getLxGatewayUrl();// LxConfigUtils.GetConfigValueByKey("lxGatewayUrl");

            String url = requestUrl + "/v1/messages/create?app_token=" + appToken;
            ExtLxMessageEntity param = new ExtLxMessageEntity();
            String msgtype = "text";
            param.setUserIdList(userIdList);
            param.setMsgType(msgtype);
            ExtLxMessageReminder reminder = new ExtLxMessageReminder();
            reminder.setAll(false);
            reminder.setUserIds(userIdList);
            ExtLxMessageText text = new ExtLxMessageText();
            text.setContent(content);
            text.setReminder(reminder);
            ExtLxMessageData data = new ExtLxMessageData();
            data.setText(text);
            param.setMsgData(data);
            String response = HttpRequestUtil.sendPost(url, JSON.toJSONString(param));
            System.out.println("[蓝信发送消息]:" + response + ",URL:" + url);
            LXResult lxResult = JSONObject.parseObject(response, LXResult.class);
            if (lxResult.getErrCode().equals("0")) {
                resultObj.setCode((ResultEnum.RESULT_SUCCESS.getCode()));
                resultObj.setMsg(ResultEnum.RESULT_SUCCESS.getMsg());
            } else {
                resultObj.setCode((ResultEnum.RESULT_FAIL.getCode()));
                resultObj.setMsg(lxResult.getErrMsg());
            }

        } catch (Exception exception) {
            resultObj.setCode(ResultEnum.RESULT_EXCEPTION.getCode());
            resultObj.setMsg(ResultEnum.RESULT_EXCEPTION.getMsg());
        }
        return resultObj;
    }

    public String getstaffId(String appToken, String phone) {
        String staffId = "";
        String requestUrl = lxProp.getLxGatewayUrl();
//        LxConfigUtils.GetConfigValueByKey("lxGatewayUrl");
        String orgid = lxProp.getOrgid();
//        LxConfigUtils.GetConfigValueByKey("orgid");
        String idType = "mobile";
        String idValue = "86-" + phone;
        String url = requestUrl + "/v2/staffs/id_mapping/fetch?app_token=" + appToken + "&org_id=" + orgid + "&id_type=" + idType + "&id_value=" + idValue;
        String result = HttpRequestUtil.doGetJson(url);
        System.out.println("蓝信获取staffId:" + result + ",URL:" + url);
        LXResult<AppToken> token = new LXResult<AppToken>();
        LXResult lxResult = JSONObject.parseObject(result, LXResult.class);
        if (lxResult.getErrCode().equals("0")) {
            ExtLxStaffRes staffRes = JSONObject.parseObject(JsonUtil.ToJson(lxResult.getData()), ExtLxStaffRes.class);
            staffId = staffRes.getStaffId();
        } else {
            log.error("[蓝信信息发送],获取staffid失败,手机号:" + phone + ",错误信息:" + lxResult.getErrCode());
        }
        return staffId;
    }

    public String getAppToken() {
        LXResult<AppToken> token = new LXResult<>();
        try {
            String requestUrl = lxProp.getLxGatewayUrl();
            //LxConfigUtils.GetConfigValueByKey("lxGatewayUrl");
            String appid = lxProp.getAppid();// LxConfigUtils.GetConfigValueByKey("appid");
            String grantType = lxProp.getAppgrant_type();// LxConfigUtils.GetConfigValueByKey("appgrant_type");
            String secret = lxProp.getAppSecret();// LxConfigUtils.GetConfigValueByKey("AppSecret");
            String url = requestUrl + "/v1/apptoken/create?grant_type=" + grantType + "&appid=" + appid + "&secret=" + secret;
            String result = HttpRequestUtil.doGetJson(url);
            System.out.println("蓝信获取用户信息:" + result + ",URL:" + url);
            LXResult lxResult = JSONObject.parseObject(result, LXResult.class);
            if (lxResult.getErrCode().equals("0")) {
                AppToken appToken = JSONObject.parseObject(JsonUtil.ToJson(lxResult.getData()), AppToken.class);
                token.setData(appToken);
            } else {
                log.error("[蓝信信息发送],获取appToken失败,错误信息:" + lxResult.getErrCode());
            }
            token.setErrCode(lxResult.getErrCode());
            token.setErrMsg(lxResult.getErrMsg());
        } catch (Exception exception) {
            log.error("[蓝信信息发送],获取appToken异常:" + exception.getMessage());
        }

        return token.getData().getAppToken();
    }

    private static String getFinalSql(String timeField, String sql) {
        /* SELECT service_code, service_name, COUNT("id") FROM sys_req_detail
                                        WHERE app_code = 'DYHSYB'
                                        AND req_time

                req_time>= '2025-06-20 00:00:00.000'
                AND req_time < '2025-06-20 23:59:59.999'
                GROUP BY service_code, service_name
                 */
        String today = LocalDate.now().toString();
        LocalTime now = LocalTime.now();
        String t1 = today + " " + now.minusHours(1).toString().substring(0, 2) + ":00:00";
        String t2 = today + " " + now.toString().substring(0, 2) + ":00:00";
        String replaced = " " + timeField + " >= '" + t1 + "' and " + timeField + " < '" + t2 + "' ";
        sql = sql.replace(timeField, replaced);
        return sql;
    }

    @Override
    public String addJob(SysMsgPush sysMsgPush) {
        String bizType = sysMsgPush.getBizType();
        SysMsgPush one = sysMsgPushMapper.getOne(bizType);
        if (one != null) {
            return "job exit，add fail";
        }
        try {
            Integer lock = lock(sysMsgPush);
            if (lock == 1) {
                sysMsgPush.setId(IdWorker2.createStrId());
                sysMsgPush.setStatus("1");
                Date now = new Date();
                String loginAccount = SysUserUtils.getLoginAccount();
                sysMsgPush.setCreatedTime(now);
                sysMsgPush.setCreatedUser(loginAccount);
                sysMsgPush.setUpdatedTime(now);
                sysMsgPush.setUpdatedUser(loginAccount);
                sysMsgPushMapper.add(sysMsgPush);
                return "add ok";
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            unlock(sysMsgPush);
        }
        return "add fail";
    }

    @Override
    public String updateJob(SysMsgPush sysMsgPush) {
        try {
            Integer lock = lock(sysMsgPush);
            if (lock == 1) {
                sysMsgPush.setUpdatedTime(new Date());
                sysMsgPush.setUpdatedUser(SysUserUtils.getLoginAccount());
                sysMsgPushMapper.updateJob(sysMsgPush);
                return "update ok";
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            unlock(sysMsgPush);
        }
        return "update fail";
    }

    public Integer lock(SysMsgPush sysMsgPush) {
        try {
            return sysMsgPushMapper.lock(sysMsgPush);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    @Override
    public Map<String, Object> pageJob(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<SysMsgPush> list = sysMsgPushMapper.getAll();
        PageInfo<SysMsgPush> pageInfo = new PageInfo<>(list);
        Map<String, Object> map = new HashMap<>();
        map.put("total", pageInfo.getTotal());
        map.put("rows", pageInfo.getList());
        return map;
    }


    public Integer unlock(SysMsgPush sysMsgPush) {
        try {
            return sysMsgPushMapper.unlock(sysMsgPush);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
}
